home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: gfx.cpp
- //
- // Desc: Graphics routines
- //
- // Copyright (C) 1995-2001 Microsoft Corporation. All Rights Reserved.
- //-----------------------------------------------------------------------------
- #include "duel.h"
- #include "gfx.h"
- #include "diutil.h"
- #include "ddutil.h"
-
-
- //-----------------------------------------------------------------------------
- // Globals
- //-----------------------------------------------------------------------------
- extern BOOL g_bFullscreen; // Window or fullscreen mode ?
- extern HWND g_hwndMain; // Main window
- extern DWORD g_dwKeys;
- extern int g_nProgramState; // Current state of program
- extern RECT g_rcWindow; // Client window rectangle
- extern HINSTANCE g_hInst; // Application instance handle
-
-
- LPDIRECTDRAW g_pDD = NULL; // DirectDraw interface
- LPDIRECTDRAWPALETTE g_pArtPalette = NULL; // Game screen palette
- LPDIRECTDRAWPALETTE g_pSplashPalette = NULL; // Splash screen palette
- LPDIRECTDRAWSURFACE g_pddsFrontBuffer = NULL; // primary surface
- LPDIRECTDRAWSURFACE g_pddsBackBuffer = NULL; // back buffer for animation
- LPDIRECTDRAWSURFACE g_pddsShip[4]; // ship bitmaps
- LPDIRECTDRAWSURFACE g_pddsNumbers; // Numbers bitmap
- DWORD g_dwFillColor;
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: InitGraphics()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT InitGraphics()
- {
- DDCAPS ddcaps;
- HRESULT hr;
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
-
- // Create a window
- g_hwndMain = CreateWindowEx( WS_EX_APPWINDOW, TEXT("DuelClass"),
- TEXT("Duel"), WS_POPUP | WS_SYSMENU, 0, 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL, NULL, g_hInst, NULL );
- if( NULL == g_hwndMain )
- return E_FAIL;
-
- UpdateWindow( g_hwndMain );
- SetFocus( g_hwndMain );
-
- // DDraw stuff begins here
- if( FAILED( hr = DirectDrawCreate( NULL, &g_pDD, NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_DDC);
- return E_FAIL;
- }
-
- // Set access mode based on fullscreen/window
- if( g_bFullscreen )
- {
- hr = g_pDD->SetCooperativeLevel( g_hwndMain,
- DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
- }
- else
- {
- hr = g_pDD->SetCooperativeLevel( g_hwndMain,
- DDSCL_NORMAL);
- }
-
- if( FAILED(hr) )
- {
- ShowError(IDS_DDRAW_ERROR_SCL);
- return E_FAIL;
- }
-
- if( g_bFullscreen )
- {
- // Set the mode to 640 by 480 by 8
- if( FAILED( g_pDD->SetDisplayMode( 640, 480, 8 ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_SDM);
- return E_FAIL;
- }
- }
- else
- {
- RECT rcWork;
- RECT rc;
- DWORD dwStyle;
-
- // If we are still a WS_POPUP window we should convert to a
- // normal app window so we look like a windows app.
- dwStyle = GetWindowStyle(g_hwndMain);
- dwStyle &= ~WS_POPUP;
- dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
- SetWindowLong( g_hwndMain, GWL_STYLE, dwStyle );
-
- // Aet window size
- SetRect( &rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y );
-
- AdjustWindowRectEx( &rc, GetWindowStyle(g_hwndMain),
- GetMenu(g_hwndMain) != NULL,
- GetWindowExStyle(g_hwndMain) );
-
- SetWindowPos( g_hwndMain, NULL, 0, 0, rc.right-rc.left,
- rc.bottom-rc.top,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
-
- SetWindowPos( g_hwndMain, HWND_NOTOPMOST, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
- // Make sure our window does not hang outside of the work area
- SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
- GetWindowRect( g_hwndMain, &rc );
- if( rc.left < rcWork.left ) rc.left = rcWork.left;
- if( rc.top < rcWork.top ) rc.top = rcWork.top;
- SetWindowPos( g_hwndMain, NULL, rc.left, rc.top, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
- }
-
- // Check the color key hardware capabilities
- ddcaps.dwSize = sizeof( ddcaps );
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
-
- if( g_bFullscreen )
- {
- // Create surfaces
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX;
- ddsd.dwBackBufferCount = 1;
- if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer,
- NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
- return E_FAIL;
- }
-
- // Get a pointer to the back buffer
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- if( FAILED( hr = g_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
- &g_pddsBackBuffer ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_GAS);
- return E_FAIL;
- }
- }
- else
- {
- LPDIRECTDRAWCLIPPER pcClipper;
-
- // Window case, create the primary surface
- // and create a backbuffer in offscreen memory
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- if( FAILED( g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer, NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
- return E_FAIL;
- }
-
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = MAX_DEFWIN_X;
- ddsd.dwHeight = MAX_DEFWIN_Y;
- if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
- return E_FAIL;
- }
-
- if( FAILED( hr = g_pDD->CreateClipper( 0, &pcClipper, NULL) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CC);
- return E_FAIL;
- }
-
- if( FAILED( hr = pcClipper->SetHWnd( 0, g_hwndMain) ) )
- {
- pcClipper->Release();
- ShowError(IDS_DDRAW_ERROR_SH);
- return E_FAIL;
- }
-
- if( FAILED( hr = g_pddsFrontBuffer->SetClipper( pcClipper) ) )
- {
- pcClipper->Release();
- ShowError(IDS_DDRAW_ERROR_SC);
- return E_FAIL;
- }
-
- // Done with clipper
- pcClipper->Release();
- }
-
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
-
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
-
- for( DWORD i=0; i<4; i++ )
- {
- if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsShip[i], NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
- return E_FAIL;
- }
- }
-
- ddsd.dwHeight = 16;
- if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsNumbers, NULL ) ) )
- {
- ShowError(IDS_DDRAW_ERROR_CREATESURFACE);
- return E_FAIL;
- }
-
- if( FAILED( RestoreSurfaces() ) )
- {
- ShowError(IDS_DDRAW_ERROR_RS);
- return E_FAIL;
- }
-
- g_dwKeys = 0;
- ShowWindow( g_hwndMain, SW_SHOW);
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: CleanupGraphics()
- // Desc:
- //-----------------------------------------------------------------------------
- VOID CleanupGraphics()
- {
- for( DWORD i=0; i<4; i++ )
- if( g_pddsShip[i] )
- g_pddsShip[i]->Release();
- if( g_pddsNumbers )
- g_pddsNumbers->Release();
- if( g_pddsFrontBuffer )
- g_pddsFrontBuffer->Release();
- if( g_pArtPalette )
- g_pArtPalette->Release();
- if( g_pSplashPalette )
- g_pSplashPalette->Release();
- if( !g_bFullscreen && g_pddsBackBuffer )
- g_pddsBackBuffer->Release();
- if( g_pDD )
- g_pDD->Release();
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: BltSplashScreen()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT BltSplashScreen( RECT* prc )
- {
- HRESULT hr;
- HBITMAP hbm;
-
- if( ( g_pddsFrontBuffer == NULL ) || ( g_pSplashPalette == NULL ) ||
- ( g_pddsBackBuffer == NULL ) )
- return E_FAIL;
-
- // Set the palette before loading the splash screen
- g_pddsFrontBuffer->SetPalette( g_pSplashPalette );
-
- hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), TEXT("SPLASH"),
- IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
- if( NULL == hbm )
- return E_FAIL;
-
- // If the surface is lost, DDUtil_CopyBitmap will fail and the surface will
- // be restored below.
- hr = DDUtil_CopyBitmap( g_pddsBackBuffer, hbm, 0, 0, 0, 0 );
-
- DeleteObject( hbm );
-
- while( 1 )
- {
- hr = g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer,
- prc, DDBLT_WAIT, NULL);
- if( SUCCEEDED(hr) )
- return S_OK;
- if( hr == DDERR_SURFACELOST )
- if( FAILED( RestoreSurfaces() ) )
- return E_FAIL;
- if( hr != DDERR_WASSTILLDRAWING )
- return E_FAIL;
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: BltNumber()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT BltNumber( CHAR* strScore, int x, int y )
- {
- while( *strScore )
- {
- RECT src;
- src.left = ((*strScore++)-'0')*16;
- src.top = 0;
- src.right = src.left + 16;
- src.bottom = src.top + 16;
-
- BltObject( x, y, g_pddsNumbers, &src, DDBLTFAST_SRCCOLORKEY );
- x += 16;
- }
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: BltObject()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT BltObject( int x, int y, LPDIRECTDRAWSURFACE pdds, RECT* prc,
- DWORD flags )
- {
- if( NULL == pdds )
- return E_FAIL;
-
- while( 1 )
- {
- HRESULT hr = g_pddsBackBuffer->BltFast( x, y, pdds, prc, flags );
- if( FAILED(hr) )
- {
- if( hr == DDERR_WASSTILLDRAWING )
- continue;
-
- if( hr == DDERR_SURFACELOST )
- if( SUCCEEDED( RestoreSurfaces() ) )
- continue;
- return E_FAIL;
- }
-
- return S_OK;
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: EraseScreen()
- // Desc:
- //-----------------------------------------------------------------------------
- VOID EraseScreen()
- {
- // Erase the background
- DDBLTFX ddbltfx;
- ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
- ddbltfx.dwSize = sizeof(ddbltfx);
- #ifdef NONAMELESSUNION
- ddbltfx.u5.dwFillColor = g_dwFillColor;
- #else
- ddbltfx.dwFillColor = g_dwFillColor;
- #endif
-
- while( 1 )
- {
- HRESULT hr = g_pddsBackBuffer->Blt( NULL, NULL, NULL,
- DDBLT_COLORFILL, &ddbltfx );
- if( SUCCEEDED(hr) )
- return;
-
- if( hr == DDERR_SURFACELOST )
- {
- if( FAILED( RestoreSurfaces() ) )
- return;
- }
-
- if( hr != DDERR_WASSTILLDRAWING )
- return;
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: FlipScreen()
- // Desc:
- //-----------------------------------------------------------------------------
- VOID FlipScreen()
- {
- // Flip the surfaces
- if( g_bFullscreen )
- {
- while( 1 )
- {
- HRESULT hr = g_pddsFrontBuffer->Flip( NULL, 0 );
-
- if( hr == DDERR_SURFACELOST )
- {
- if( FAILED( RestoreSurfaces() ) )
- return;
- }
- if( hr != DDERR_WASSTILLDRAWING )
- return;
- }
- }
- else
- {
- g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer, NULL,
- DDBLT_WAIT, NULL );
- }
- }
-
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: RestoreSurfaces()
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT RestoreSurfaces()
- {
- HRESULT hr;
- HBITMAP hbm;
-
- if( FAILED( hr = g_pddsFrontBuffer->Restore() ) )
- return hr;
- if( FAILED( hr = g_pddsBackBuffer->Restore() ) )
- return hr;
-
- for( DWORD i=0; i<4; i++ )
- if( FAILED( hr = g_pddsShip[i]->Restore() ) )
- return hr;
-
- // Create and set the palette for the splash bitmap
- g_pSplashPalette = DDUtil_LoadPalette( g_pDD, TEXT("SPLASH") );
- if( NULL == g_pSplashPalette )
- return E_FAIL;
-
- // Create and set the palette for the art bitmap
- g_pArtPalette = DDUtil_LoadPalette( g_pDD, TEXT("Duel8") );
- if( NULL == g_pArtPalette )
- return E_FAIL;
-
- // set the palette before loading the art
- g_pddsFrontBuffer->SetPalette( g_pArtPalette );
-
- hbm = (HBITMAP)LoadImage( GetModuleHandle(NULL), TEXT("Duel8"),
- IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
- if( NULL == hbm )
- return E_FAIL;
-
- if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[0], hbm, 0, 0, 320, 128 ) ) )
- {
- DeleteObject( hbm );
- return E_FAIL;
- }
-
- if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[1], hbm, 0, 128, 320, 128 ) ) )
- {
- DeleteObject( hbm );
- return E_FAIL;
- }
-
- if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[2], hbm, 0, 256, 320, 128 ) ) )
- {
- DeleteObject( hbm );
- return E_FAIL;
- }
-
- if( FAILED( hr = DDUtil_CopyBitmap( g_pddsShip[3], hbm, 0, 384, 320, 128 ) ) )
- {
- DeleteObject( hbm );
- return E_FAIL;
- }
-
- if( FAILED( hr = DDUtil_CopyBitmap( g_pddsNumbers, hbm, 0, 512, 320, 16 ) ) )
- {
- DeleteObject( hbm );
- return E_FAIL;
- }
-
- DeleteObject( hbm );
-
- // set colorfill colors and colorkeys according to bitmap contents
- g_dwFillColor = DDUtil_ColorMatch( g_pddsShip[0], CLR_INVALID );
-
- DDUtil_SetColorKey( g_pddsShip[0], CLR_INVALID );
- DDUtil_SetColorKey( g_pddsShip[1], CLR_INVALID );
- DDUtil_SetColorKey( g_pddsShip[2], CLR_INVALID );
- DDUtil_SetColorKey( g_pddsShip[3], CLR_INVALID );
- DDUtil_SetColorKey( g_pddsNumbers, CLR_INVALID );
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: SetGamePalette()
- // Desc:
- //-----------------------------------------------------------------------------
- VOID SetGamePalette()
- {
- if( g_pddsFrontBuffer )
- g_pddsFrontBuffer->SetPalette( g_pArtPalette );
- }
-
-
-
-
-